/* 

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串，则返回空字符串 "" 。

注意：如果 s 中存在这样的子串，我们保证它是唯一的答案。

 

示例 1：

输入：s = "ADOBECODEBANC", t = "ABC"
输出："BANC"
示例 2：

输入：s = "a", t = "a"
输出："a"
 

提示：

1 <= s.length, t.length <= 105
s 和 t 由英文字母组成
 

进阶：你能设计一个在 o(n) 时间内解决此问题的算法吗？

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/minimum-window-substring
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。

*/

// 题解：https://leetcode-cn.com/problems/minimum-window-substring/solution/tong-su-qie-xiang-xi-de-miao-shu-hua-dong-chuang-k/
// 滑动窗口
/**
 * @param {string} s
 * @param {string} t
 * @return {string}
 */
var minWindow = function (s, t) {
    const need = new Map();

    for (const char of t) {
        need.set(char, need.get(char) ? need.get(char) + 1 : 1);
    }

    let needCnt = t.length;
    let minLen = Infinity;
    let left = 0,
        right = Infinity;
    let i = j = 0;

    for (; j < s.length; j++) {
        if (need.get(s[j]) > 0) {
            needCnt -= 1;
        }
        need.set(s[j], need.get(s[j]) - 1);

        if (needCnt === 0) {
            while (true) {
                if (need.get(s[i]) === 0) {
                    break;
                }
                need.set(s[i], need.get(s[i]) + 1);
                i += 1;
            }

            if (j - i + 1 < minLen) {
                left = i;
                right = j;
                minLen = j - i + 1;
            }

            need.set(s[i], need.get(s[i]) + 1);
            needCnt += 1;
            i += 1;
        }
    }

    // 如果right始终没被更新过，代表无满足条件的结果
    return right === Infinity ? "" : s.substring(left, right + 1);
};